use std::{env, fs::File, path::PathBuf};

use clap::Parser;
use log::LevelFilter;
use simplelog::{CombinedLogger, Config, SharedLogger, TermLogger, WriteLogger};

use crate::server::start_server;
use anyhow::Result;

mod server;

#[derive(Debug, Parser)]
#[clap(name = "FileServer", bin_name = "file-server", long_about = "文件服务")]
#[clap(author, version, about="一个简易的文件服务器", long_about = None)]
struct FileServer {
    #[clap(
        short,
        long,
        value_parser,
        default_value = "127.0.0.1:5000",
        help = "服务host"
    )]
    bind: String,
    #[clap(short, long, value_parser, default_value = ".", help = "根目录地址")]
    root: PathBuf,
    #[clap(short, long, value_parser, help = "日志文件")]
    log: Option<String>,
    #[clap(long, value_parser, default_value = "Info")]
    log_level: LevelFilter,
    #[clap(long, value_parser, help = "在浏览器打开", default_value = "false")]
    browser: bool,
}

#[tokio::main]
async fn main() -> Result<()> {
    let args: FileServer = FileServer::parse();
    let mut loggers: Vec<Box<dyn SharedLogger>> = vec![TermLogger::new(
        args.log_level,
        Config::default(),
        simplelog::TerminalMode::Mixed,
        simplelog::ColorChoice::Auto,
    )];
    if args.log.is_some() {
        loggers.push(WriteLogger::new(
            args.log_level,
            Config::default(),
            File::create(args.log.unwrap()).unwrap(),
        ))
    }
    CombinedLogger::init(loggers).unwrap();
    let bind = args.bind.as_str();
    let root = match args.root.to_str() {
        Some(".") => env::current_dir().unwrap(),
        Some(_) | None => args.root,
    };
    start_server(bind, root, args.browser).await?;
    log::info!("Shutting down.");
    Ok(())
}
